// 引入WebSocket类
thin.imports('https://gitee.com/rjry/iCdn/raw/master/static/ws/ws.js');
// 引入控制台调试类
thin.imports('https://gitee.com/rjry/iCdn/raw/master/static/xDebug/1.0.0/xDebug.js');

thin.use(function() {

    // xDebug | 调试开关
    xDebug.onoff = true;

    // 常量 | 启动投注的封盘倒计时(秒)
    const BET_CLOSE_TIME_COUNTDOWN   = 120;
    // 常量 | 投注后获取排期的延时时间(秒)
    const GET_SCHEME_DELAY_AFTER_BET = 45;

    // 实例对象
    var self   = this;
    // WebSocket
    var socket = null;
    // 计时器
    var timer  = null;
    // 定时器
    var timeo  = {
        // 倍率变化 重新投注
        odds:null,
        // 投注成功 延时获取排期
        five:null,
        // 封盘 延时获取排期
        beok:null
    };
    // 投注开关
    var onoff  = false;
    // 全局数据
    var gData = {
        // 接口授权
        jwt: thin.data['data-jwt'],
        // 账户信息
        account: {
            // 账户余额
            balance: 0,
            // 账户盈亏
            profit: 0
        },
        // 注单投注
        bet: {
            // 投注编号
            phaseid: '',
            // 号码赔率
            uPI_P: '',
            // 投注标识
            JeuValidate: ''
        },
        // 当前排期
        scheme:{
            // 期号
            issue: '',
            // 封盘时间
            close_time: 0,
        },
        // 控制台
        console:{
            // 状态 0-停止 1-启动
            state: 0
        },
        // 封盘倒计时
        closeTime: 0
    };


    // +-----------------------------------------------------------------------------------------------------------
    // | 预处理
    // +-----------------------------------------------------------------------------------------------------------
    
    // 第一步 初始化socket
    initSocket();



    // +-----------------------------------------------------------------------------------------------------------
    // | 流程控制
    // +-----------------------------------------------------------------------------------------------------------

    // 初始化socket
    function initSocket(){
        const self = this;
        endSocket();

        socket = new WS();
        socket.init({
            ping:30,
            onopen:function(){
                xDebug.clear();
                xDebug.console('::WebSocket连接成功::','#fff','success');
                xDebug.console('>>> 控制台已激活，请回到软件启动自动投注','success');
            },
            onclose:function(){
                xDebug.console('::WebSocket连接断开::','#fff','error');
                endSocket();
                xDebug.console('>>> 3.5s后重新发起连接','info');
                setTimeout(initSocket,3500);
            },
            onerror:function(evt){
                xDebug.console('::WebSocket连接异常::','#fff','error');
                endSocket();
            },
            onmessage:function(evt){
                var res  = JSON.parse(evt.data);
                var data = res.data || {};
                // console.log(res)
                if(res.type == 'console_to_client'){
                    switch(data.cmd){
                        case 'get_account_balance':
                            // 收到需要排期信息反馈账户信息指令
                            // .....
                            // 
                            // 反馈账户信息
                            if(gData.console.state == 1) sendAccoutBlance();
                            break;
                        case 'get_current_scheme':
                            // 收到需要排期信息指令
                            // .....
                            // 
                            // 反馈排期信息
                            if(gData.console.state == 1) sendCurrentScheme();
                            break;
                        case 'handle_scheme':
                            // 收到启动/停止指令
                            gData.console.state = data.state;
                            if(gData.console.state == 1){
                                xDebug.action('启动自动投注');
                                // 重新获取排期
                                getAccountInfo(accountInfocb);
                                // 反馈是否投注的状态 [发送指令]
                                sendBetState(0);
                            }else{
                                // 停止投注
                                xDebug.action('停止自动投注');
                                closeTimer();
                                closeTimeo();
                            }
                            // 客户端已收到停止/关闭的指令 [指令]
                            reciveBetState(data.state)
                            break;
                        default:
                    }
                }
            }
        })
        
        socket.connect("wss://lotcz.kojo.club/socket?jwt="+gData.jwt+"&role=client");
    }
    


    // +-----------------------------------------------------------------------------------------------------------
    // | 业务封装
    // +-----------------------------------------------------------------------------------------------------------
    
    // 获取胆位排期
    function getAccountInfo(callback){
        var data_opt = {
            action: "get_oddsinfo",
            playid: "1,5,9,13,17,21,24,27,30,33",
            playpage: "xyft5_d1_10"
        };
        $.ajax({
            url: "/L_XYFT5/Handler/Handler.ashx",
            data: data_opt,
            type: 'POST',
            cache: false,
            dataType: "json",
            timeout: 30000,
            success: function(data) {
                xDebug.action('获取排期结果');
                callback(data);
            },
            error: function(data) {
                xDebug.echo('获取排期异常');
                console.dir(data)
            }
        });
    }

    // 下注 胆位投注
    function setAccountBet(data_opt){
        var resdata = {
            action: 'put_money',
            phaseid: gData.bet.phaseid,  //期号
            oddsid: data_opt.oddsid.join(), // 号码
            uPI_P: data_opt.uPI_P.join(),  // 倍率
            uPI_M: data_opt.uPI_M.join(), // 金额
            i_index: getArrIndex(data_opt.uPI_M), // 下标
            JeuValidate: gData.bet.JeuValidate,
            playpage: 'xyft5_d1_10'
        };

        $.ajax({
            url: "/L_XYFT5/Handler/Handler.ashx",
            data: resdata,
            type: 'POST',
            cache: false,
            contentType:"application/x-www-form-urlencoded; charset=UTF-8",
            dataType: "json",
            timeout: 30000,
            success: function(data) {
                xDebug.action('执行投注结果');
                isBeted(data);
            },
            error: function(data) {
                xDebug.echo('投注异常');
                console.dir(data)
            }
        });
    }

    // 获取方案
    function getScheme(){
        var data_opt = JSON.stringify({
            cmd: "fr.scheme.get",
            ident: Math.random(),
            jwt: gData.jwt,
            params:{}
        });
        $.ajax({
            url: "https://lotcz.kojo.club/api",
            data: data_opt,
            type: 'POST',
            cache: false,
            contentType:"application/x-www-form-urlencoded; charset=UTF-8",
            dataType: "json",
            timeout: 10000,
            success: function(data) {
                xDebug.action('获取方案结果');
                beforeToBet(data);
            },
            error: function(data) {
                xDebug.echo('获取方案异常');
                console.dir(data)
            }
        });
    }

    /**
     *  获取排期 [初始入口]
     *  第一步、转换倍率
     *  第二步、设置全局的值
     *  第三步、同步控制台数据
     *  第四步、启动计时器
     */
    function accountInfocb(data){
        if(data.success == 200){
            
            xDebug.console('>>> 获取排期成功','primary');
            var res = data.data;
            
            // 第一步、转换倍率
            var play_odds = res.play_odds;
            var play_odd  = {};
            for(var i in play_odds){
                play_odd[String((i.split('_'))[1])] = play_odds[i].pl;
            }
            
            // 第二步、设置全局的值
            var closeTime = timeTosec(res.stop_time);
            gData.account = {
                balance:Number(res.usable_credit || '0'), // 账户余额
                profit:Number(res.profit || '0') // 盈亏
            }
            gData.scheme = {
                issue:res.nn, // profit
                close_time:closeTime // 封盘倒计时
            }
            gData.bet.phaseid = res.p_id; // 投注编号
            gData.bet.uPI_P   = play_odd; // 号码赔率
            gData.closeTime   = closeTime;
            // 仅初次时获取页面存储变量，往后通过投注结果动态更新
            if(gData.bet.JeuValidate == '') gData.bet.JeuValidate = document.getElementById("mainIframe").contentWindow.JeuValidate;
            
            
            // 第三步、同步控制台数据
            // 发送账户余额
            sendAccoutBlance()
            // 发送排期信息
            sendCurrentScheme()
            
            // 第四步、启动计时器
            // 先关闭已存在的计时器，再重新开启新的计时器
            closeTimer();
            createTimer();
        }else if(data.success == 300){

        }else if(data.success == 400){
            
        }else if(data.success == 600){

        }
    }

    /**
     * 获取排期 [投注前]
     *  第一步、转换倍率
     *  第二步、更新全局的值
     *  第三步、同步控制台数据
     *  第四步、重启计时器
     *  第五步、获取方案
     */
    function beforeGetScheme(data){
        if(data.success == 200){
            var res = data.data;

            // 第一步、转换倍率
            var play_odds = res.play_odds;
            var play_odd  = {};
            for(var i in play_odds){
                play_odd[String((i.split('_'))[1])] = play_odds[i].pl;
            }
            
            // 第二步、设置全局的值
            var closeTime = timeTosec(res.stop_time);
            gData.account = {
                balance:Number(res.usable_credit || '0'), // 账户余额
                profit:Number(res.profit || '0') // 盈亏
            }
            gData.scheme = {
                issue:res.nn, // profit
                close_time:closeTime // 封盘倒计时
            }
            gData.bet.phaseid = res.p_id; // 投注编号
            gData.bet.uPI_P   = play_odd; // 号码赔率
            gData.closeTime  = closeTime;
        
            // 第三步、同步控制台数据
            // 发送账户余额
            sendAccoutBlance()
            // 发送排期信息
            sendCurrentScheme()
            
            // 第四步、重启计时器
            // 先关闭已存在的计时器，再重新开启新的计时器
            closeTimer();
            createTimer();
            
            // 第五步、获取方案
            // 触发获取排期然后下注
            getScheme();
        }else if(data.success == 300){

        }else if(data.success == 400){
            
        }else if(data.success == 600){

        }
    }
    
    /**
     * 投注前处理数据
     * 第一步  格式化方案的投注编号和投注金额
     * 第二步  格式化倍率
     * 第三步  整合投注提交数据
     * 第四步  执行投注
     */
    function beforeToBet(data){
        var scheme = JSON.parse(data || "{}");
            var oddsid = [];
            var uPI_M  = [];
            for(var i in scheme){
                if(Number(scheme[i]) > 0){
                    oddsid.push(Number(i));
                    uPI_M.push(Number(scheme[i]));
                }
            }
            
            // 第二步  格式化倍率
            var uPI_P = [];
            for(var i=0;i<oddsid.length;i++){
                uPI_P.push(gData.bet.uPI_P[String(oddsid[i])]);
            }
            
            // 第三步  整合投注提交数据
            var bet_data = {
                oddsid: oddsid,
                uPI_P: uPI_P,
                uPI_M: uPI_M
            };

            // 第四步  执行投注
            setAccountBet(bet_data);
    }

    /**
     * 投注后回调函数
     */
    function isBeted(data){
        if(data.success == 200){
            xDebug.console('>>> 投注成功，5s后更新账户余额','primary');
            
            // 更新下期投注标识
            gData.bet.JeuValidate = data.data.JeuValidate;

            // 反馈投注成功 [发送指令]
            sendBetState(1)
            
            // 延时五秒 重新获取排期信息
            closeTimeo('five');
            timeo.five = setTimeout(function(){
                if(gData.console.state == 1){
                    getAccountInfo(accountInfocb)
                }
            },5 * 1000);

        } else if (data.success == 400) {
            xDebug.console('>>> '+data.tipinfo,'primary');
            gData.bet.JeuValidate = data.data.JeuValidate;

        } else if(data.success == 600){

            // 赔率变化 重新投注
            closeTimeo('odds');
            timeo.odds = setTimeout(function(){
                if(gData.console.state == 1){
                    getAccountInfo(beforeGetScheme);
                }
            },1600)
        }
    }

    // 关闭socket
    function endSocket(){
        if(socket){
            socket.close();
            socket = null;
        }
    }

    // 关闭倒计时
    function closeTimer(){
        if(timer) {
            // xDebug.action('销毁计时器');
            clearInterval(timer);
            timer = null;
        }
    }

    // 关闭定时器
    function closeTimeo(key){
        if(key){
            if(timeo[key]){
                clearTimeout(timeo[key]);
                timeo[key] = null;
            }
        }else{
            for(var i in timeo){
                clearTimeout(timeo[key]);
                timeo[i] = null;
            }
        }
    }

    // 发送账户余额 [指令]
    function sendAccoutBlance(){
        socket.send({"type":"client_to_console","data":{
            "cmd":"reply_account_balance",
            "account":gData.account
        }})
    }

    // 发送排期信息 [指令]
    function sendCurrentScheme(){
        socket.send({"type":"client_to_console","data":{
            "cmd":"reply_current_scheme",
            "scheme":gData.scheme
        }})
    }

    // 发送排期信息 [指令]
    function sendBetState(state){
        socket.send({"type":"client_to_console","data":{
            "cmd":"reply_bet_state",
            "console":{
                "bet":{
                    "state":state
                }
            }
        }})
    }

    // 客户端已收到停止/关闭的指令 [指令]
    function reciveBetState(state){
        socket.send({"type":"client_to_console","data":{
            "cmd":"reply_scheme",
            "console":{
                "state":state
            }
        }})
    }



    // +-----------------------------------------------------------------------------------------------------------
    // | 工具函数
    // +-----------------------------------------------------------------------------------------------------------

    // 获取下标
    function getArrIndex(arr){
        var x = [];
        for(var i=0;i<arr.length;i++) {x.push(i);}
        return x.join();
    }

    // 时间转秒数
    function timeTosec(time){
        var t = time.split(":");
        if(t.length == 3){
            return Number(t[0]*3600)+Number(t[1]*60)+Number(t[2]);
        }else if(t.length == 2){
            return Number(t[0]*60)+Number(t[1]);
        }else if(t.length == 1){
            return Number(t[0]);
        }
        return 0;
    }

    
    
    // 创建定时器
    function createTimer(){

        gData.closeTime -= 1;
        
        timer = setInterval(function(){
            if(gData.closeTime > 0 && gData.closeTime < BET_CLOSE_TIME_COUNTDOWN && onoff === false) {
                // 开始投注
                onoff = true;
                xDebug.console('::开始投注::','#fff','primary');
                getAccountInfo(beforeGetScheme);
            }
            if(gData.closeTime <= 0) {
                // xDebug.console('>>> 倒计时结束,销毁定时器','primary');
                closeTimer();

                // 封盘后延时五十秒 重新获取排期信息
                xDebug.console('>>> 已封盘，'+GET_SCHEME_DELAY_AFTER_BET+'s后将获取下场排期','primary');
                
                closeTimeo('beok');
                timeo.beok = setTimeout(function(){
                    if(gData.console.state == 1){
                        getAccountInfo(accountInfocb);
                        // 反馈投注成功 [发送指令]
                        sendBetState(0);
                    }
                },GET_SCHEME_DELAY_AFTER_BET * 1000);

                onoff = false;
                return;
            }
            gData.closeTime -= 1;
        },1000)
    }
    
    
});